<?php

namespace common\Http;

use Log;
use Exception;
use GuzzleHttp\Client;
use Common\Manager\CacheManager;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\RequestException;//请求异常

/**
 * 只处理返回html或文本数据的HTTP请求客户端
 *
 * @package Common\Http
 */
class HtmlHttpClient
{
    use CacheManager;
    /**
     * 错误代码
     * @var int
     */
    public static $errorCode = null;
    /**
     * 错误消息
     * @var string
     */
    public static $errorMessage = null;

    /**
     * 默认的请求配置
     * @see http://docs.guzzlephp.org/en/latest/request-options.html
     */
    private static $config = [
        'timeout'           => 5.14,// 请求超时时间
        'connect_timeout'   => 5.14,//等待服务器响应的超时时间（秒）
        'http_errors'       => true,//抛出如 4xx 和 5xx 异常(一定要，以作异常处理)
        'allow_redirects'   => false,//禁止自动跳转
        //'proxy'           => '192.168.16.1:10',//代理服务器
        //HTTP报文头信息
        'headers' => [
            'Accept'     => 'application/json',
            'User-Agent' => 'isz.com/1.0'
        ]
    ];

    /**
     * GET方法请求一个地址并附加查询参数
     * @param string $url
     * @param array $query
     * @return bool|mixed
     */
    public static function get(string $url, array $query = []){
        try {
            $client = new Client(self::$config);
            $options['query'] = $query;
            $promise = $client->getAsync($url, $options);
            $body = $promise->then(
                function (ResponseInterface $res) {
                    /** @var \Psr\Http\Message\ResponseInterface $res */
                    $body     = $res->getBody()->getContents();//获取请求结果
                    return $body;
                },
                function (RequestException $e)  {
                    throw $e;
                }
            )->wait();
        }
        catch (RequestException $e) {
            self::error($e->getCode(), '请求异常');
            return self::exception('GET', $url, $options, $e);
        }
        catch (Exception $e) {
            self::error($e->getCode(), $e->getMessage());
            return self::exception('GET', $url, $options, $e);
        }

        return $body;
    }
    /**
     * 异常日志记录
     * @param $method
     * @param string $uri
     * @param array $options
     * @param \Exception $e
     * @return boolean
     */
    private static function exception(string $method, string $uri = '', array $options = [], Exception $e){
        $message = [
            'Uri' => $uri,
            'Client' => self::class,
            'Method' => $method,
            'Params' => $options,
            'Code' => $e->getCode(),
            'File' => $e->getFile(),
            'Line' => $e->getLine(),
            //'Trace' => $e->getTraceAsString(),//堆栈太多，尽量不要
            'Message' => trim($e->getMessage()),
        ];
        Log::error(json_encode($message));
        return false;//发生异常时，统一返回值为 false
    }
    /**
     * 设置类错误消息
     * @param $code
     * @param $message
     */
    private static function error($code, $message){
        self::$errorCode = $code;
        self::$errorMessage = $message;
    }
}